package com.truyen.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.googlecode.ehcache.annotations.Cacheable;
import com.truyen.persistence.dao.TruyenTranhDao;
import com.truyen.persistence.entity.TacGia;
import com.truyen.persistence.entity.ChapterTam;
import com.truyen.persistence.entity.ChapterTruyenTranh;
import com.truyen.persistence.entity.ChapterTmpTruyenTranh;
import com.truyen.persistence.entity.TruyenTranh;
import com.truyen.service.ChapterTamService;
import com.truyen.service.ChapterTruyenTranhService;
import com.truyen.service.ChapterTmpTruyenTranhService;
import com.truyen.service.TruyenTranhService;
import com.truyen.utils.PagingInfo;


@Service
public class TruyenTranhServiceImpl implements TruyenTranhService {
	
	@Autowired
	private TruyenTranhDao truyenTranhDao;
	
	@Autowired
	private ChapterTruyenTranhService chapterTruyenTranhService;
	
	@Autowired
	private ChapterTmpTruyenTranhService chapterTmpTruyenTranhService;
	
	@Autowired
	private ChapterTamService chapterTamService;

	@Override
	public void save(TruyenTranh entity) {
		truyenTranhDao.save(entity);
	}

	@Override
	public TruyenTranh findById(Long id) {
		return truyenTranhDao.findById(id);
	}

	@Override
	public List<TruyenTranh> getAll() {
		return truyenTranhDao.findAll();
	}

	@Override
	public TruyenTranh findByProperty(String column, Object value) {
		List<TruyenTranh> lst = truyenTranhDao.findByProperty(column, value);
		return (lst.size() > 0)?lst.get(0):null;
	}

	@Override
	public List<TruyenTranh> getLstComicLinkImageNullBlogTruyen(int sourceBy){
		return truyenTranhDao.getLstComicLinkImageNullBlogTruyen(sourceBy);
	}

	@Override
	@Cacheable(cacheName="truyenTranhCacheDataController")
	public List<TruyenTranh> getAllLst(String kwSearch, String sort, String sortBy,	PagingInfo pInfo) {
		return truyenTranhDao.getAllLst(kwSearch,sort,sortBy,pInfo);
	}

	@Override
	public void setHot(Long id) {
		try{
			TruyenTranh entity = findById(id);
			boolean isHot = entity.getIsHot();
			if(isHot){
				entity.setIsHot(false);
			}else{
				entity.setIsHot(true);
			}
			truyenTranhDao.merge(entity);
		}catch (Exception e) {
			// TODO: handle exception
		}
	}

	@Override
	public void setIsDelete(Long id) {
		try{
			TruyenTranh entity = findById(id);
			boolean isDelete = entity.getIsDelete();
			if(isDelete){
				entity.setIsDelete(false);
			}else{
				entity.setIsDelete(true);
			}
			truyenTranhDao.merge(entity);
		}catch (Exception e) {
			// TODO: handle exception
		}
	}
	
	@Override
	@Cacheable(cacheName="lstTruyenTranhCacheTruyenController")
	public List<TruyenTranh> getListTruyenBy(String orderByColumn,int begin, int max) {
		return truyenTranhDao.getListTruyenBy(orderByColumn,begin,max);
	}

	@Override
	public List<TruyenTranh> getListTruyenRandom(int maxLimit) {
		return truyenTranhDao.getListTruyenRandomBy(maxLimit);
	}

	@Override
	public void updateTotalChapterr(Long id, float totalChapter) {
		try{
			TruyenTranh entity = findById(id);
			entity.setTotalChapter(totalChapter);
			truyenTranhDao.merge(entity);
		}catch (Exception e) {
			// TODO: handle exception
		}
	}

	@Override
	public List<TruyenTranh> getLstTruyenBySourceBy(int sourceBy) {
		return truyenTranhDao.getLstTruyenBySourceBy(sourceBy);
	}

	@Override
	public void updateViews(Long id, long views, long viewsWeek, long viewsMonth) {
		try{
			TruyenTranh entity = findById(id);
			entity.setViews(views);
			entity.setViewsWeek(viewsWeek);
			entity.setViewsMonth(viewsMonth);
			truyenTranhDao.merge(entity);
		}catch (Exception e) {
			// TODO: handle exception
		}
	}

	@Override
	@Cacheable(cacheName="lstTruyenTranhTimKiemCacheTruyenController")
	public List<TruyenTranh> getLstByProperty(String column, Object value, int begin, int maxLimit) {
		return truyenTranhDao.getLstByProperty(column,value, begin, maxLimit);
	}

	@Override
	public List<Object> getObjectByNameUnsigned(String kwSearch, int max, String typeSearch) {
		return truyenTranhDao.getObjectByNameUnsigned(kwSearch,max,typeSearch);
	}

	@Override
	public List<TruyenTranh> getLstByPropertyWithPaging(String column, String value, String sortBy, PagingInfo pInfo) {
		return truyenTranhDao.getLstByPropertyWithPaging(column, value, sortBy, pInfo);
	}

	@Override
	public void updateLiked(Long idTruyen, long liked) {
		try{
			TruyenTranh entity = findById(idTruyen);
			entity.setLiked(liked);
			truyenTranhDao.merge(entity);
		}catch (Exception e) {
			// TODO: handle exception
		}
	}

	@Override
	@Transactional
	public void delete(Long id) {
		try{
			TruyenTranh entity = findById(id);
			List<ChapterTam> lstChapterTam = chapterTamService.getByTruyen(entity);
			if(lstChapterTam != null){
				int sizeList = lstChapterTam.size();
				for(int i=0;i<sizeList;i++){
					ChapterTam chapterTam = lstChapterTam.get(i);
					chapterTamService.delete(chapterTam.getId());
				}
			}
			List<ChapterTmpTruyenTranh> lstchapterTmpTruyenTranh = chapterTmpTruyenTranhService.getByTruyen(entity);
			if(lstchapterTmpTruyenTranh != null){
				int sizeList = lstchapterTmpTruyenTranh.size();
				for(int i=0;i<sizeList;i++){
					ChapterTmpTruyenTranh chapterTmpTruyenTranh = lstchapterTmpTruyenTranh.get(i);
					ChapterTruyenTranh chapterTruyenTranh = chapterTmpTruyenTranh.getChapterTruyenTranh();
					chapterTruyenTranhService.delete(chapterTruyenTranh.getId());
					chapterTmpTruyenTranhService.delete(chapterTmpTruyenTranh.getId());
				}
			}
			truyenTranhDao.delete(entity);
		}catch (Exception e) {
			// TODO: handle exception
		}
	}

	@Override
	@Transactional
	public void updateColumnString(long id, String column, String value) {
		try {
			TruyenTranh entity = findById(id);
			if(column.equals("linkImage")){
				entity.setLinkImage(value);
			}
			truyenTranhDao.merge(entity);
		} catch (Exception e) {
			// TODO: handle exception
		}
		
	}

	@Override
	@Cacheable(cacheName="lstTruyenTranhOrderByCacheTruyenController")
	public List<TruyenTranh> getLstByPropertyWithOrderByPaging(String orderBy, PagingInfo pInfo) {
		return truyenTranhDao.getLstByPropertyWithOrderByPaging(orderBy,pInfo);
	}

	@Override
	public List<TruyenTranh> getLstByTacGiaWithPaging(TacGia tacGia, String orderBy, PagingInfo pInfo) {
		return truyenTranhDao.getLstByTacGiaWithPaging(tacGia,orderBy,pInfo);
	}

	@Override
	public List<TruyenTranh> getLstByTacGiaLimit(TacGia tacGia, int begin, int maxLimit) {
		return truyenTranhDao.getLstByTacGiaLimit(tacGia, begin, maxLimit);
	}

	@Override
	public void update(Long idTruyen, String name, String alias,
			String linkImage, String nameImage, String info, TacGia tacGia,
			String categories, float totalChapter, boolean isDelete,
			boolean isFinished, boolean isHot, long liked, long views,
			long viewsWeek, long viewsMonth, int sourceBy,
			String linkSource, String translator) {
		try {
				TruyenTranh entity = findById(idTruyen);
				if(entity != null){
					entity.setName(name);
					entity.setAlias(alias);
					entity.setLinkImage(linkImage);
					entity.setNameImage(nameImage);
					entity.setInfo(info);
					entity.setTacGia(tacGia);
					entity.setCategories(categories);
					entity.setTotalChapter(totalChapter);
					entity.setIsDelete(isDelete);
					entity.setIsFinished(isFinished);
					entity.setIsHot(isHot);
					entity.setLiked(liked);
					entity.setViews(views);
					entity.setViewsWeek(viewsWeek);
					entity.setViewsMonth(viewsMonth);
					entity.setSourceBy(sourceBy);
					entity.setLinkSource(linkSource);
					entity.setTranslator(translator);
					truyenTranhDao.merge(entity);
				}
		} catch (Exception e) {
			// TODO: handle exception
		}
		
	}

	@Async
	@Override
	public void updateViewsWeek() {
		List<TruyenTranh> lstTruyen = getAll();
		if(lstTruyen.size() > 0){
			int size = lstTruyen.size();
			for(int i=0; i < size; i++){
				TruyenTranh truyen = lstTruyen.get(i);
				truyen.setViewsWeek(0);
				truyenTranhDao.merge(truyen);
			}
		}
	}

	@Async
	@Override
	public void updateViewsMonth() {
		List<TruyenTranh> lstTruyen = getAll();
		if(lstTruyen.size() > 0){
			int size = lstTruyen.size();
			for(int i=0; i < size; i++){
				TruyenTranh truyen = lstTruyen.get(i);
				truyen.setViewsMonth(0);
				truyenTranhDao.merge(truyen);
			}
		}
	}

}
